package com.yunban.project.api.text_check.service.impl;

import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationOutput;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.JsonUtils;
import com.alibaba.fastjson2.JSON;
import com.yunban.project.api.text_check.domain.CorrectionConfig;
import com.yunban.project.api.text_check.enums.CorrectionModel;
import com.yunban.project.api.text_check.service.AiCorrectionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @author: lijiajun
 * @date: 2025-03-07
 * @version: 1.0
 */
@Slf4j
@Service("aliyunCorrectionService")
public class AliyunCorrectionService implements AiCorrectionService {
    @Override
    public String correction(String text, CorrectionConfig config, String taskId) {
        Generation gen = new Generation();
        Message userMsg = Message.builder()
                .role(Role.USER.getValue())
                .content(config.getPromptPrefix() + text)
                .build();
        GenerationParam param = GenerationParam.builder()
                // 若没有配置环境变量，请用百炼API Key将下行替换为：.apiKey("sk-xxx")
                .apiKey(config.getApiKey())
                // 此处以qwen-plus为例，可按需更换模型名称。模型列表：https://help.aliyun.com/zh/model-studio/getting-started/models
                .model(config.getAiModel())
                .messages(Collections.singletonList(userMsg))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .build();

        try {
            GenerationResult call = gen.call(param);
            log.info("调用成功，结果为：{}", call);
            if (ObjectUtils.isEmpty(call)
                    || ObjectUtils.isEmpty(call.getOutput())
                    || CollectionUtils.isEmpty(call.getOutput().getChoices())) {
                return null;
            }
            List<GenerationOutput.Choice> choices = call.getOutput().getChoices();
            Message message = choices.get(0).getMessage();
            if (ObjectUtils.isEmpty(message)) {
                return null;
            }
            String content = message.getContent();
            // 如果纠错后的输出格式中，不包含“输出：”“分类：”“来源：” 那么则跳过
            if (!content.contains("输出：") && !content.contains("分类：") && !content.contains("来源：")) {
                log.info("DeepSeek 纠正结果不包含\"输出：\"\"分类：\"\"来源：\"，跳过本次纠正");
                return null;
            }
            return this.formatResponse(content, text);
        } catch (Exception ex) {
            log.error("【AliyunCorrectionServiceImpl.correction】阿里云通义千问模型：文本纠错异常", ex);
            log.error("【AliyunCorrectionServiceImpl.correction】阿里云通义千问模型：文本纠错异常：{}", ex.getMessage());
            return null;
        }
    }

    public static void main(String[] args) {
        AliyunCorrectionService service = new AliyunCorrectionService();
        CorrectionConfig correctionConfig = new CorrectionConfig();
        correctionConfig.setName("通义千问");
        correctionConfig.setCode(CorrectionModel.TONG_YI);
        correctionConfig.setApiKey("sk-5d19d1ac5371453d9c9ff3ef5aa6de2c");
        correctionConfig.setPromptPrefix("#角色名称: 文本纠错助手\n" +
                "#风格特点:\n" +
                "\n" +
                "1. 采用五维文本问题分类框架（新增错误等级维度），涵盖固定用法、标点符号、语法错误、敏感词和标准用法\n" +
                "2. 专注执行文本基础层面的校对工作，具备逐字核对的严谨性 \n" +
                "3. 错误等级标准：\n" +
                "    一级（最严重）：存在影响语义理解的错别字、铭感词、严重歧义的错误、违反规范导致文章阅读不顺等等（例如你豪、很高兴认识腻）\n" +
                "    二级（一般）：固定搭配、语义错误（例：的地得不分、错误量词）\n" +
                "    三级（可以忽略）：标点错用、文章通顺角度的建议性修改（例：\"进行改革\"改为\"实施改革\"）\n" +
                "4. 处理过程保持绝对中立，对涉及敏感内容执行关键词替换/进行自动过滤\n" +
                "5. 遵循严格的格式要求，执行标点符号转换时仅处理明确指定的类型\n" +
                "6. 纠正错误时最大限度保留原文结构和表达意图\n" +
                "7. 不返回除了纠错文本以外的任何内容\n" +
                "8. 输出结果严格遵循输出格式项，不包含其他内容\n" +
                "9. 不添加未包含的标点符号，严格保持原文本段落结构\n" +
                "10. 在输出内容中也要体现这个纠错的参考文献来源来自于哪里\n" +
                "11. 不管在什么情况下，都要严禁额外的加入“<br/>”字符\n" +
                "12. 如果纠错后文本只是多出了一个<br/>，那么只需要按照原文本输出就行\n" +
                "13. 不要对纠错文本中的“<br/>”做任何纠错服务，如果纠错文本结尾是“<br/>”，那么后面不要补充任何内容，包括标点符号\n" +
                "\n" +
                "#能力限制:\n" +
                "1. 不处理文档排版、字体格式等非文本内容\n" +
                "2. 不进行政治敏感度判断，仅执行关键词替换操作\n" +
                "3. 不添加原文未包含的标点符号\n" +
                "4. 不提供文本润色或风格优化服务\n" +
                "5. 对文本中错误的标点符号的使用也要进行纠错\n" +
                "6. 不管在什么情况下，都要严禁额外的加入“<br/>”字符\n" +
                "7. 如果纠错后只加了一个<br/>，那么只需要按照原文本输出就行\n" +
                "8. 不要对纠错文本中的“<br/>”做任何纠错服务，如果纠错文本结尾是“<br/>”，那么后面不要补充任何内容，包括标点符号\n" +
                "9. 不处理超过5000字的批量文本任务\n" +
                "\n" +
                "#输出格式\n" +
                "输出：纠错后文本。分类：问题类型 错误等级：x级 来源：来源于哪个参考文献/书\n" +
                "\n" +
                "#示例：\n" +
                "输出：根据最新数据显示，企业营收同比增长15%。分类：固定用法 错误等级：x级 来源：《新华社新闻报道用语规范（2023）》\n" +
                "\n" +
                "注：错误等级判定标准\n" +
                "一级：影响语义的文字错误/语法结构错误/敏感词/核心数据错误（例：将\"增长15%\"误为\"下降15%\"、将\"你好呀\"误为\"你号呀\"）\n" +
                "二级：固定搭配错误（例：的地得不分/错误量词）\n" +
                "三级：标点误用/建议性修改（例：\"进行改革\"改为\"实施改革\" / 错误标点符号错误）\n" +
                "\n" +
                "\n" +
                "需纠错内容：");
        correctionConfig.setAiModel("qwen-max");
        try {
            String correction = service.correction("最终化作太阳穴的阵阵钝痛<br/>", correctionConfig, "1");
            System.out.println(correction);
        } catch (Exception ex) {
            // 使用日志框架记录异常信息
            System.err.println("An error occurred while calling the generation service: " + ex.getMessage());
        }
        System.exit(0);
    }
}
